package org.example.echoexample;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @author hh
 * @since 2024/11/2
 */
// 标注一个Handler实例可以被多个通道安全地共享（多个通道的流水线可以加入同一个Handler实例）
// 如果没有加@ChannelHandler.Sharable注解，试图将同一个Handler实例添加到多个ChannelPipeline时，Netty将会抛出异常。
/*
  如何判断一个Handler是否为@Sharable呢？
    ChannelHandlerAdapter提供了实用方法——isSharable()。如果其对
    应的实现加上了@Sharable注解，那么这个方法将返回true，表示它可
    以被添加到多个ChannelPipeline中。
 */
@ChannelHandler.Sharable
public class NettyEchoServerHandler extends ChannelInboundHandlerAdapter {

    public static final NettyEchoServerHandler INSTANCE = new NettyEchoServerHandler();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf) msg;
        System.out.println("msg type: " + ((in.hasArray()) ? "堆内存" : "直接内存"));
        int len = in.readableBytes();
        byte[] arr = new byte[len];
        in.getBytes(0, arr);
        System.out.println("server received: " + new String(arr, "utf-8"));

        System.out.println("写回前，msg.refCnt: " + ((ByteBuf) msg).refCnt());
//        // 写回数据，异步任务
//        ChannelFuture f = ctx.writeAndFlush(msg);
//        f.addListener((ChannelFutureListener) -> {
//            System.out.println("写回后，msg.refCnt: " + ((ByteBuf) msg).refCnt());
//        });
    }
}
